package com.kama.server.netty;


import com.kama.server.provider.ServiceProvider;
import com.kama.server.ratelimit.RateLimit;
import com.kama.trace.interceptor.ServerTraceInterceptor;
import common.message.RequestType;
import common.message.RpcRequest;
import common.message.RpcResponse;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ClassName NettyRpcServerHandler
 * @Description 服务端处理器
 * @Author Xu
 * @LastChangeDate 2023-12-02 10:26
 * @Version v5.0
 */
@AllArgsConstructor  // 使用 Lombok 自动生成构造器
@Slf4j
// 基于 Netty 的 RPC 服务器端处理器，它用于处理接收到的 RPC 请求，并返回相应的结果。
public class NettyRpcServerHandler extends SimpleChannelInboundHandler<RpcRequest> {

    private final ServiceProvider serviceProvider;  // 确保通过构造器注入 ServiceProvider

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest request) throws Exception {
        if (request == null) {
            log.error("接收到非法请求，RpcRequest 为空");
            return;
        }
        // 如果是心跳包则直接返回
        if(request.getType() == RequestType.HEARTBEAT){
            log.info("接收到来自客户端的心跳包");
            return;
        }
        // 正常的请求处理
        if(request.getType() == RequestType.NORMAL) {
            //trace记录
            ServerTraceInterceptor.beforeHandle();
            // RPC 响应生成：通过 getResponse(request) 方法获取对应的 RpcResponse
            RpcResponse response = getResponse(request);
            //ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);

            //trace上报
            ServerTraceInterceptor.afterHandle(request.getMethodName());

            ctx.writeAndFlush(response);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("处理请求时发生异常: ", cause);
        ctx.close();
    }

    private RpcResponse getResponse(RpcRequest rpcRequest) {
        //得到服务名
        String interfaceName = rpcRequest.getInterfaceName();

        //接口限流降级
        RateLimit rateLimit = serviceProvider.getRateLimitProvider().getRateLimit(interfaceName);
        if (!rateLimit.getToken()) {
            //如果获取令牌失败，进行限流降级，快速返回结果
            log.warn("服务限流，接口: {}", interfaceName);
            return RpcResponse.fail("服务限流，接口 " + interfaceName + " 当前无法处理请求。请稍后再试。");
        }

        //得到服务端相应服务实现类
        Object service = serviceProvider.getService(interfaceName);
        //反射调用方法
        Method method;
        try {
            method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamsType());
            Object invoke = method.invoke(service, rpcRequest.getParams());
            // 方法调用成功，返回相应的执行结果
            return RpcResponse.sussess(invoke);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            log.error("方法执行错误，接口: {}, 方法: {}", interfaceName, rpcRequest.getMethodName(), e);
            return RpcResponse.fail("方法执行错误");
        }
    }
}
